package com.rightsidetech.system.service.impl;

import com.rightsidetech.commom.base.ResponseData;
import com.rightsidetech.commom.enums.CodeIdEnum;
import com.rightsidetech.commom.push.Device;
import com.rightsidetech.commom.push.EnumMsgType;
import com.rightsidetech.commom.push.PushModel;
import com.rightsidetech.commom.push.StorePushUtil;
import com.rightsidetech.commom.utils.DateUtil;
import com.rightsidetech.system.dtos.request.store.StoreAppBackReq;
import com.rightsidetech.system.dtos.request.store.StoreAppCodeLoginReq;
import com.rightsidetech.system.dtos.request.store.StoreAppLoginReq;
import com.rightsidetech.system.dtos.request.store.StoreAppRegistReq;
import com.rightsidetech.system.dtos.response.store.AppLoginInfoResp;
import com.rightsidetech.system.dtos.response.store.StoreAppLoginResp;
import com.rightsidetech.system.dtos.response.store.StoreNamInfoResp;
import com.rightsidetech.system.entity.SysAgentInfo;
import com.rightsidetech.system.entity.store.SysStoreInfo;
import com.rightsidetech.system.entity.store.SysStoreLoginHistory;
import com.rightsidetech.system.entity.store.SysStoreLoginInfo;
import com.rightsidetech.system.mapper.SysAgentInfoMapper;
import com.rightsidetech.system.mapper.SysStoreInfoMapper;
import com.rightsidetech.system.mapper.SysStoreLoginHistoryMapper;
import com.rightsidetech.system.mapper.SysStoreLoginInfoMapper;
import com.rightsidetech.system.service.StoreLoginInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.UUID;

/**
 * @Package: com.rightsidetech.system.service.impl
 * @ClassName: StoreLoginInfoServiceImpl
 * @Author: yinj
 * @CreateTime: 2021/11/04 13:58
 * @Description: TODO
 */
@Slf4j
@Service("storeLoginInfoServiceImpl")
public class StoreLoginInfoServiceImpl implements StoreLoginInfoService {

    @Resource
    private SysStoreLoginInfoMapper sysStoreLoginInfoMapper;
    @Resource
    private SysStoreLoginHistoryMapper sysStoreLoginHistoryMapper;
    @Resource
    private SysStoreInfoMapper sysStoreInfoMapper;
    @Resource
    private SysAgentInfoMapper sysAgentInfoMapper;


    @Override
    public ResponseData<StoreAppLoginResp> login(StoreAppLoginReq req) {
        SysStoreLoginInfo storeLoginInfo = sysStoreLoginInfoMapper.selectByLogin(req.getLoginName());
        if (ObjectUtils.isEmpty(storeLoginInfo)) {
            return ResponseData.fail(CodeIdEnum.NOACCOUNT);
        }
        if (storeLoginInfo.getStatus() == -1) {
            return ResponseData.fail("账号已停用,请联系平台处理");
        }
        SysStoreInfo sysStoreInfo = sysStoreInfoMapper.selectByPrimaryKey(storeLoginInfo.getStoreId());
        if (ObjectUtils.isEmpty(sysStoreInfo)){
            return ResponseData.fail(CodeIdEnum.NonStoreInfo);
        }
        if (sysStoreInfo.getStatus() == -1) {
            return ResponseData.fail("门店已关闭营业,无法登录");
        }
        ResponseData<StoreAppLoginResp> responseData = new ResponseData<>();
        String encodePass = DigestUtils.md5DigestAsHex((req.getPassword() + storeLoginInfo.getSalt()).getBytes());
        if (!storeLoginInfo.getPassword().equals(encodePass)) {
            responseData.setCodeId(CodeIdEnum.FAILED.getValue());
            responseData.setCodeDes("密码错误");
            return responseData;
        }
        SysStoreLoginHistory loginHistory = sysStoreLoginHistoryMapper.selectHistory(storeLoginInfo.getId());
        Date date = new Date();
        // 原登录记录置为过期
        if (loginHistory != null
                && loginHistory.getLogoutTime() == null) {
            SysStoreLoginHistory history = new SysStoreLoginHistory();
            history.setEffectiveTime(date);
            history.setLogoutTime(date);
            history.setLoginInfoId(loginHistory.getLoginInfoId());
            sysStoreLoginHistoryMapper.updateBatch(history);
        }
        //更新token
        String token = UUID.randomUUID().toString().replace("-", "");
        SysStoreLoginInfo loginInfo = new SysStoreLoginInfo();
        loginInfo.setId(storeLoginInfo.getId());
        loginInfo.setToken(token);
        sysStoreLoginInfoMapper.updateByPrimaryKeySelective(loginInfo);

        //添加登录记录
        SysStoreLoginHistory history = new SysStoreLoginHistory();
        history.setLoginInfoId(storeLoginInfo.getId());
        history.setEffectiveTime(DateUtil.addDate(date, 14));
        history.setLoginTime(date);
        history.setLoginIp(req.getClientIp());
        history.setDeviceId(req.getDeviceId());
        history.setDeviceType(req.getDeviceType());
        sysStoreLoginHistoryMapper.insertSelective(history);

        //登录成功给退出设备发推送
        if (loginHistory != null && loginHistory.getDeviceType() != 3 && !StringUtils.isEmpty(loginHistory.getDeviceId())) {
            if (!loginHistory.getDeviceId().equals(req.getDeviceId())) {
                if(!StringUtils.isEmpty(loginHistory) && !StringUtils.isEmpty(loginHistory.getEffectiveTime()) && System.currentTimeMillis() <= loginHistory.getEffectiveTime().getTime()){
                    loginOutPush(loginHistory.getDeviceId(), loginHistory.getDeviceType(), loginInfo.getId().toString(), EnumMsgType.APP_LOGIN_OUT.getName(), EnumMsgType.APP_LOGIN_OUT.getValue());
                    log.info("推送---给被退出设备通知成功");
                }
            }
        }

        StoreAppLoginResp loginResponse = new StoreAppLoginResp(token, storeLoginInfo.getStoreId(), storeLoginInfo.getLoginName(), storeLoginInfo.getMobileNo());
        responseData.setCodeDes(CodeIdEnum.Success.getName());
        responseData.setCodeId(CodeIdEnum.Success.getValue());
        responseData.setResData(loginResponse);
        return responseData;
    }

    @Override
    public ResponseData<StoreAppLoginResp> codeLogin(StoreAppCodeLoginReq req) {
        SysStoreLoginInfo storeLoginInfo = sysStoreLoginInfoMapper.selectByLogin(req.getPhoneNo());
        if (ObjectUtils.isEmpty(storeLoginInfo)) {
            return ResponseData.fail(CodeIdEnum.NOACCOUNT);
        }
        if (storeLoginInfo.getStatus() == -1) {
            return ResponseData.fail("账号已停用,请联系平台处理");
        }
        SysStoreInfo sysStoreInfo = sysStoreInfoMapper.selectByPrimaryKey(storeLoginInfo.getStoreId());
        if (ObjectUtils.isEmpty(sysStoreInfo)){
            return ResponseData.fail(CodeIdEnum.NonStoreInfo);
        }
        if (sysStoreInfo.getStatus() == -1) {
            return ResponseData.fail("门店已关闭营业,请联系平台处理");
        }
        ResponseData<StoreAppLoginResp> responseData = new ResponseData<>();
        SysStoreLoginHistory loginHistory = sysStoreLoginHistoryMapper.selectHistory(storeLoginInfo.getId());
        Date date = new Date();
        // 原登录记录置为过期
        if (loginHistory != null
                && loginHistory.getLogoutTime() == null) {
            SysStoreLoginHistory history = new SysStoreLoginHistory();
            history.setEffectiveTime(date);
            history.setLogoutTime(date);
            history.setLoginInfoId(loginHistory.getLoginInfoId());
            sysStoreLoginHistoryMapper.updateBatch(history);
        }
        //更新token
        String token = UUID.randomUUID().toString().replace("-", "");
        SysStoreLoginInfo loginInfo = new SysStoreLoginInfo();
        loginInfo.setId(storeLoginInfo.getId());
        loginInfo.setToken(token);
        sysStoreLoginInfoMapper.updateByPrimaryKeySelective(loginInfo);

        //添加登录记录
        SysStoreLoginHistory history = new SysStoreLoginHistory();
        history.setLoginInfoId(storeLoginInfo.getId());
        history.setEffectiveTime(DateUtil.addDate(date, 14));
        history.setLoginTime(date);
        history.setLoginIp(req.getClientIp());
        history.setDeviceId(req.getDeviceId());
        history.setDeviceType(req.getDeviceType());
        sysStoreLoginHistoryMapper.insertSelective(history);

        //登录成功给退出设备发推送
        if (loginHistory != null && loginHistory.getDeviceType() != 3 && !StringUtils.isEmpty(loginHistory.getDeviceId())) {
            if (!loginHistory.getDeviceId().equals(req.getDeviceId())) {
                loginOutPush(loginHistory.getDeviceId(), loginHistory.getDeviceType(), loginInfo.getId().toString(), EnumMsgType.APP_LOGIN_OUT.getName(), EnumMsgType.APP_LOGIN_OUT.getValue());
                log.info("推送---给被退出设备通知成功");
            }
        }

        StoreAppLoginResp loginResponse = new StoreAppLoginResp(token, storeLoginInfo.getStoreId(), storeLoginInfo.getLoginName(), storeLoginInfo.getMobileNo());
        responseData.setCodeDes(CodeIdEnum.Success.getName());
        responseData.setCodeId(CodeIdEnum.Success.getValue());
        responseData.setResData(loginResponse);
        return responseData;
    }

    @Override
    public ResponseData logout(Long loginId) {
        SysStoreLoginInfo storeLoginInfo = sysStoreLoginInfoMapper.selectByPrimaryKey(loginId);
        if (ObjectUtils.isEmpty(storeLoginInfo)){
            return ResponseData.fail(CodeIdEnum.NOACCOUNT);
        }
        sysStoreLoginInfoMapper.delToken(storeLoginInfo.getId());

        SysStoreLoginHistory loginHistory = sysStoreLoginHistoryMapper.selectHistory(storeLoginInfo.getId());
        Date date = new Date();
        // 原登录记录置为过期
        if (loginHistory != null
                && loginHistory.getLogoutTime() == null) {
            SysStoreLoginHistory history = new SysStoreLoginHistory();
            history.setEffectiveTime(date);
            history.setLogoutTime(date);
            history.setLoginInfoId(loginHistory.getLoginInfoId());
            sysStoreLoginHistoryMapper.updateBatch(history);
        }
        return ResponseData.success();
    }

    @Override
    public ResponseData<AppLoginInfoResp> getLoginInfo(Long storeInfoId) {

        SysStoreLoginInfo storeLoginInfo = sysStoreLoginInfoMapper.selectByStoreInfoId(storeInfoId);
        if (ObjectUtils.isEmpty(storeLoginInfo)){
            return ResponseData.fail(CodeIdEnum.EMPTY_DATA);
        }
        AppLoginInfoResp resp = new AppLoginInfoResp();
        SysStoreInfo sysStoreInfo = sysStoreInfoMapper.selectByPrimaryKey(storeLoginInfo.getStoreId());
        if (!ObjectUtils.isEmpty(sysStoreInfo)){
            BeanUtils.copyProperties(sysStoreInfo,resp);
            resp.setAdress(StringUtils.isEmpty(sysStoreInfo.getDoorplate()) ? sysStoreInfo.getAdress() : sysStoreInfo.getAdress() + sysStoreInfo.getDoorplate());
            resp.setStoreId(sysStoreInfo.getId());
            SysAgentInfo sysAgentInfo = sysAgentInfoMapper.selectByPrimaryKey(sysStoreInfo.getSysAgentInfoId());
            if (!ObjectUtils.isEmpty(sysAgentInfo)){
                resp.setCustomerMobileNo(sysAgentInfo.getCustomerMobileNo());
            }
        }
        return ResponseData.success(resp);
    }

    @Override
    public ResponseData regist(StoreAppRegistReq req) {
        SysStoreLoginInfo loginInfo = sysStoreLoginInfoMapper.selectByLogin(req.getPhoneNo());
        if (!ObjectUtils.isEmpty(loginInfo)){
            return ResponseData.fail("手机号已注册,请登录");
        }
        //查询是否添加过门店信息
//        SysStoreInfo storeInfo = sysStoreInfoMapper.selectByPhoneNo(req.getPhoneNo());
        Long storeId = 0L;
//        if (!ObjectUtils.isEmpty(storeInfo)){
//            storeId = storeInfo.getId();
//        }
        SysStoreLoginInfo loginInfo1 = new SysStoreLoginInfo();
        loginInfo1.setStoreId(storeId);
        loginInfo1.setLoginName(req.getPhoneNo());
        loginInfo1.setSalt(String.valueOf(Math.random() * 900000 + 100000));
        loginInfo1.setPassword(DigestUtils.md5DigestAsHex((req.getPassWord() + loginInfo1.getSalt()).getBytes()));
        loginInfo1.setMobileNo(req.getPhoneNo());
        loginInfo1.setCreatedAt(new Date());
        loginInfo1.setCreaterId(0L);
        sysStoreLoginInfoMapper.insertSelective(loginInfo1);

        return ResponseData.success("注册成功");
    }

    @Override
    public ResponseData back(StoreAppBackReq req) {
        SysStoreLoginInfo loginInfo = sysStoreLoginInfoMapper.selectByMobileNo(req.getPhoneNo());
        if(ObjectUtils.isEmpty(loginInfo)){
            return ResponseData.fail(CodeIdEnum.NOACCOUNT);
        }
        if(loginInfo.getStatus() != 0){
            return ResponseData.fail(CodeIdEnum.ACCOUNTSTOP);
        }
        SysStoreInfo sysStoreInfo = sysStoreInfoMapper.selectByPrimaryKey(loginInfo.getStoreId());
        if(ObjectUtils.isEmpty(sysStoreInfo)){
            return ResponseData.fail(CodeIdEnum.NonStoreInfo);
        }
        if(sysStoreInfo.getStatus() == -1){
            return ResponseData.fail(CodeIdEnum.StoreStop);
        }

        SysStoreLoginInfo loginInfo1 = new SysStoreLoginInfo();
        loginInfo1.setId(loginInfo.getId());
        loginInfo1.setPassword(DigestUtils.md5DigestAsHex((req.getPassWord() + loginInfo.getSalt()).getBytes()));
        sysStoreLoginInfoMapper.updateByPrimaryKeySelective(loginInfo1);

        sysStoreLoginInfoMapper.delToken(loginInfo.getId());

        SysStoreLoginHistory loginHistory = sysStoreLoginHistoryMapper.selectHistory(loginInfo.getId());
        Date date = new Date();
        // 原登录记录置为过期
        if (loginHistory != null
                && loginHistory.getLogoutTime() == null) {
            SysStoreLoginHistory history = new SysStoreLoginHistory();
            history.setEffectiveTime(date);
            history.setLogoutTime(date);
            history.setLoginInfoId(loginHistory.getLoginInfoId());
            sysStoreLoginHistoryMapper.updateBatch(history);
        }
        return ResponseData.success("密码修改成功,请重新登录");
    }

    @Override
    public StoreNamInfoResp selectName(Long storeId) {
        return sysStoreInfoMapper.selectName(storeId);
    }


    /**
     * 推送消息
     * @param deviceId
     * @param deviceTag
     * @param accountId
     * @param text
     * @param type
     */
    private void loginOutPush(String deviceId, Byte deviceTag, String accountId, String text, Byte type) {
        PushModel model = new PushModel();
        model.setTitle("超威云商门店端");
        model.setText(text);
        model.setUnReadNum(1);
        model.setStringId(accountId);
        model.setPushType(type);
        Device device = new Device();
        device.setDeviceId(deviceId);
        device.setDeviceType(deviceTag.intValue());
        device.setRiderId(accountId);
        try {
            StorePushUtil.pushToSingle(device, model);
            log.info(text + "推送成功");
        } catch (Exception e) {
            log.error(text + "推送失败", e);
        }
    }
}
